Tensors

Qtea Tensor

class qtealeaves.tensors.QteaTensor(links, ctrl='Z', are_links_outgoing=None, base_tensor_cls=None, dtype=<class 'numpy.complex128'>, device=None)[source]

Dense tensor for Quantum Tea simulations using numpy or cupy as underlying arrays and linear algebra.

Arguments

linkslist of integers

Dimension along each link.

ctrlstr | scalar, optional

Initialization of tensor. Valid are “N” (uninitialized array), “Z” (zeros) “R”, “random” (random), “O” (ones), “1” or “eye” for rank-2 identity matrix, “ground” for first element equal to one, or None (elem completely not set), scalar (the tensor is filled with that scalar value, must pass np.isscalar and np.isreal checks). Default to “Z”

are_links_outgoinglist of bools, optional

Used in symmetric tensors only

base_tensor_clsvalid dense quantum tea tensor or None, optional

Used in symmetric tensors only

dtypedata type, optional

Data type for numpy or cupy. Default to np.complex128

devicedevice specification, optional

Default to “cpu”. Available: “cpu”, “gpu”

Details

Mixed-device mode

The mixed-device mode is enabled for this class allowing for devices like cpu+gpu:1. The mixed-device mode can be used for QteaTensor. Different GPUs can currently not be accessed from within a thread spanned inside simulations (other backends might support this). Tensor operation on the GPU have to be on the active cupy GPU, which we resolve by a decorator setting the active GPU in a context manager for every call. Unfortunately, not all operations can be executed on the selected device, i.e., if they happen outside the tensors module. Such operations are for example in the qtealeaves.simulation submodule; return value can be cupy-arrays with direct call of GPU kernels on the default GPU. In this case, a warning is displayed.

add_update(other, factor_this=None, factor_other=None)[source]

Inplace addition as self = factor_this * self + factor_other * other.

Arguments

othersame instance as self

Will be added to self. Unmodified on exit.

factor_thisscalar

Scalar weight for tensor self.

factor_otherscalar

Scalar weight for tensor other

are_equal(other, tol=1e-07)[source]

Check if two tensors are equal.

Define property of outgoing links as property (always False).

assert_diagonal(tol=1e-07)[source]

Check that tensor is a diagonal matrix up to tolerance.

assert_identity(tol=1e-07)[source]

Check if tensor is an identity matrix.

assert_int_values(tol=1e-07)[source]

Check that there are only integer values in the tensor.

assert_real_valued(tol=1e-07)[source]

Check that all tensor entries are real-valued.

Attach dummy link at given position (inplace update).

conj()[source]

Return the complex conjugated in a new tensor.

conj_update()[source]

Apply the complex conjugated to the tensor in place.

convert(dtype=None, device=None, stream=None)[source]

Convert underlying array to the specified data type and device inplace.

Parameters

dtypenp.dtype, optional

Type to which you want to convert. If None, no conversion. Default to None.

devicestr, optional

Device where you want to send the QteaTensor. If None, no conversion. Default to None.

streamNone | bool | cp.cuda.Stream | etc

If None, use default stream for memory communication. If boolean, new stream is used for True. If not None and bool, use a new stream for memory communication. Default to None (Use null stream).

static convert_operator_dict(op_dict, params=None, symmetries=None, generators=None, base_tensor_cls=None, dtype=<class 'numpy.complex128'>, device='cpu')[source]

Iterate through an operator dict and convert the entries. Converts as well to rank-4 tensors.

Arguments

op_dictinstance of TNOperators

Contains the operators as xp.ndarray.

paramsdict, optional

To resolve operators being passed as callable.

symmetries: list, optional, for compatibility with symmetric tensors.

Must be empty list.

generatorslist, optional, for compatibility with symmetric tensors.

Must be empty list.

base_tensor_clsNone, optional, for compatibility with symmetric tensors.

No checks on this one here.

dtypedata type for xp, optional

Specify data type. Default to np.complex128

devicestr

Device for the simulation. Available “cpu” and “gpu” Default to “cpu”

Details

The conversion to rank-4 tensors is useful for future implementations, either to support adding interactions with a bond dimension greater than one between them or for symmetries. We add dummy links of dimension one. The order is (dummy link to the left, old link-1, old link-2, dummy link to the right).

convert_singvals(singvals, dtype=None, device=None, stream=None)[source]

Convert the singular values via a tensor.

Parameters

dtypenp.dtype, optional

Type to which you want to convert. If None, no conversion. Default to None.

devicestr, optional

Device where you want to send the QteaTensor. If None, no conversion. Default to None.

streamNone | cp.cuda.Stream

If not None, use a new stream for memory communication. Default to None (Use null stream).

copy(dtype=None, device=None)[source]

Make a copy of a tensor.

property device

Device where the tensor is stored.

diag(real_part_only=False, do_get=False)[source]

Return either the diagonal of an input rank-2 tensor or a rank-2 tensor of an input diagonal.

dot(other)[source]

Inner product of two tensors <self|other>.

property dtype

Data type of the underlying arrays.

property dtype_eps

Data type’s machine precision.

dtype_from_char(dtype)[source]

Resolve data type from chars C, D, S, Z and optionally H.

Construct a dummy link. It is just the integer 1 if no symmetries are involved.

eig()[source]

Compute eigenvalues and eigenvectors of a two-leg tensor

Return

eigvals, eigvecsinstances of QteaTensor

Eigenvalues and corresponding eigenvectors of input tensor.

eig_api(matvec_func, links, conv_params, args_func=None, kwargs_func=None)[source]

Interface to hermitian eigenproblem

Arguments

matvec_funccallable

Multiplies “matrix” with “vector”

linkslinks according to QteaTensor

Contain the dimension of the problem.

conv_paramsinstance of TNConvergenceParameters

Settings for eigenproblem with Arnoldi method.

args_func : arguments for matvec_func

kwargs_func : keyword arguments for matvec_func

Returns

eigenvalues : scalar

eigenvectors : instance of QteaTensor

eig_api_arpack(matvec_func, links, conv_params, args_func=None, kwargs_func=None)[source]

Interface to hermitian eigenproblem via Arpack. Arguments see eig_api.

eig_api_qtea(matvec_func, conv_params, args_func=None, kwargs_func=None)[source]

Interface to hermitian eigenproblem via qtealeaves.solvers. Arguments see eig_api.

eigvalsh()[source]

Calculate eigendecomposition for a rank-2 tensor.

einsum(einsum_str, *others)[source]

Call to einsum with self as first tensor.

Arguments

einsum_strstr

Einsum contraction rule.

other: List[QteaTensors]

2nd, 3rd, …, n-th tensor in einsum rule as positional arguments.

Results

tensorQteaTensor

Contracted tensor according to the einsum rules.

Details

The call np.einsum(einsum_str, x.elem, y.elem, z.elem) translates into x.einsum(einsum_str, y, z) for x, y, and z being QteaTensor.

property elem

Elements of the tensor.

elementwise_abs_smaller_than(value)[source]

Return boolean if each tensor element is smaller than value

expand_tensor(link, new_dim, ctrl='R')[source]

Expand tensor along given link and to new dimension.

expm(fuse_point=None, prefactor=1)[source]

Take the matrix exponential with a scalar prefactor, i.e., Exp(prefactor * self).

Parameters

fuse_pointint, optional

If given, reshapes the tensor into a matrix by fusing links up to INCLUDING fuse_point into one, and links after into the second dimension. To compute the exponential of a 4-leg tensor, for example, by fusing (0,1),(2,3), set fuse_point=1. Default is None.

prefactorfloat, optional

Prefactor of the tensor to be exponentiated. Default to 1.

Return

matinstance of QteaTensor

Exponential of input tensor.

eye_like(link)[source]

Generate identity matrix.

Arguments

selfinstance of QteaTensor

Extract data type etc from this one here.

linksame as returned by links property, here integer.

Dimension of the square, identity matrix.

flatten()[source]

Returns flattened version (rank-1) of dense array in native array type.

static free_device_memory(device=None)[source]

Free the unused device memory that is otherwise occupied by the cache. Otherwise cupy will keep the memory occupied for caching reasons. For multi-GPU, all devices will be cleared unless you specify the device.

Parameters

devicestr | None

If present, i.e., not None, only the corresponding device will be freed. The device is a string, e.g., “gpu:0”

classmethod from_elem_array(tensor, dtype=None, device=None)[source]

New tensor from array

Arguments

tensorxp.ndarray

Array for new tensor.

dtypedata type, optional

Can allow to specify data type. If not None, it will convert. Default to None

Fuses one set of links to a single link (inplace-update).

Parameters

fuse_lowint

First index to fuse

fuse_highint

Last index to fuse.

Example: if you want to fuse links 1, 2, and 3, fuse_low=1, fuse_high=3. Therefore the function requires links to be already sorted before in the correct order.

get()[source]

Get the whole array of a tensor to the host as tensor.

get_attr(*args)[source]

High-risk resolve attribute for an operation on an elementary array.

static get_default_datamover()[source]

The default datamover compatible with this class.

get_diag_entries_as_int()[source]

Return diagonal entries of rank-2 tensor as integer on host.

get_entry()[source]

Get entry if scalar on host.

get_of(variable)[source]

Run the get method to transfer to host on variable (same device as self).

get_submatrix(row_range, col_range)[source]

Extract a submatrix of a rank-2 tensor for the given rows / cols.

getsizeof()[source]

Size in memory (approximate, e.g., without considering meta data).

is_close_identity(tol=1e-07)[source]

Check if rank-2 tensor is close to identity.

is_dtype_complex()[source]

Check if data type is complex.

is_gpu_available()[source]

Returns flag if GPU is available for this tensor class.

is_implemented_device(query)[source]

Check if argument query is an implemented device.

Parameters

querystr

String to be tested if it corresponds to a device implemented with this tensor.

Returns

is_implementedbool

True if string is available as device.

Check if the link at given index is at full bond dimension.

kron(other, idxs=None)[source]

Perform the kronecker product between two tensors. By default, do it over all the legs, but you can also specify which legs should be kroned over. The legs over which the kron is not done should have the same dimension.

Parameters

otherQteaTensor

Tensor to kron with self

idxsTuple[int], optional

Indexes over which to perform the kron. If None, kron over all indeces. Default to None.

Returns

QteaTensor

The kronned tensor

Details

Performing the kronecker product between a tensor of shape (2, 3, 4) and a tensor of shape (1, 2, 3) will result in a tensor of shape (2, 6, 12).

To perform the normal kronecker product between matrices just pass rank-2 tensors.

To perform kronecker product between vectors first transfor them in rank-2 tensors of shape (1, -1)

Performing the kronecker product only along some legs means that along that leg it is an elementwise product and not a kronecker. For Example, if idxs=(0, 2) for the tensors of shapes (2, 3, 4) and (1, 3, 2) the output will be of shape (2, 3, 8).

property linear_algebra_library

Specification of the linear algebra library used as string numpy-cupy`.

Here, as well dimension of tensor along each dimension.

mask_to_device(mask)[source]

Send a mask to the device where the tensor is. (right now only CPU –> GPU, CPU –> CPU).

mask_to_host(mask)[source]

Send a mask to the host. (right now only CPU –> GPU, CPU –> CPU).

classmethod mpi_bcast(tensor, comm, tn_mpi_types, tensor_backend, root=0)[source]

Broadcast tensor via MPI.

classmethod mpi_recv(from_, comm, tn_mpi_types, tensor_backend)[source]

Send tensor via MPI.

Arguments

from_integer

MPI process to receive tensor from.

comm : instance of MPI communicator to be used

tn_mpi_typesdict

Dictionary mapping dtype to MPI data types.

tensor_backend : instance of TensorBackend

mpi_send(to_, comm, tn_mpi_types)[source]

Send tensor via MPI.

Arguments

tointeger

MPI process to send tensor to.

comm : instance of MPI communicator to be used

tn_mpi_typesdict

Dictionary mapping dtype to MPI data types.

property ndim

Rank of the tensor.

norm()[source]

Calculate the norm of the tensor <tensor|tensor>.

norm_sqrt()[source]

Calculate the square root of the norm of the tensor, i.e., sqrt( <tensor|tensor>).

normalize()[source]

Normalize tensor with sqrt(<tensor|tensor>).

permute_rows_cols_update(inds)[source]

Permute rows and columns of rank-2 tensor with inds. Inplace update.

prepare_eig_api(conv_params)[source]

Return xp variables for eigsh.

Returns

kwargsdict

Keyword arguments for eigs call. If initial guess can be passed, key “v0” is set with value None

LinearOperatorcallable

Function generating a LinearOperator

eigshcallable

Interface with actual call to eigsh

random_unitary(links)[source]

Generate a random unitary matrix via performing a QR on a random tensor.

Arguments

selfinstance of QteaTensor

Extract data type etc from this one here.

linkssame as returned by links property, here integer.

Dimension of the tensors as [link[0], .., link[-1], link[0], .., link[-1]], random unitary matrix for contracting first/last half of legs with itself.

classmethod read(filehandle, dtype, device, base_tensor_cls, cmplx=True, order='F')[source]

Read a tensor from file.

Remove the dummy link at given position (inplace update).

reshape(shape, **kwargs)[source]

Reshape a tensor.

reshape_update(shape, **kwargs)[source]

Reshape tensor dimensions inplace.

Scale tensor along one link at link_idx with weights.

Arguments

link_weightsnp.ndarray

Scalar weights, e.g., singular values.

link_idxint

Link which should be scaled.

do_inversebool, optional

If True, scale with inverse instead of multiplying with link weights. Default to False

Returns

updated_link : instance of QteaTensor

Details

The inverse implementation handles zeros correctly which have been introduced due to padding. Therefore, scale_link should be used over passing 1 / link_weights to this function.

Scale tensor along one link at link_idx with weights (inplace update).

Arguments

link_weightsnp.ndarray

Scalar weights, e.g., singular values.

link_idxint

Link which should be scaled.

do_inversebool, optional

If True, scale with inverse instead of multiplying with link weights. Default to False

Details

The inverse implementation handles zeros correctly which have been introduced due to padding. Therefore, scale_link_update should be used over passing 1 / link_weights to this function.

set_diagonal_entry(position, value)[source]

Set the diagonal element in a rank-2 tensor (inplace update)

set_matrix_entry(idx_row, idx_col, value)[source]

Set one element in a rank-2 tensor (inplace update)

Calculate the property of a missing link in a list.

Arguments

linkslist

Contains data like returned by property links, except for one element being None

max_dimint

Maximal dimension of link allowed by convergence parameters or similar.

are_links_outgoinglist of bools

Indicates link direction for symmetry tensors only.

static set_seed(seed, devices=None)[source]

Set the seed for this tensor backend and the specified devices.

Arguments

seedlist[int]

List of integers used as a seed; list has length 4.

deviceslist[str] | None, optional

Can pass a list of devices via a string, e.g., to specify GPU by index. Default to None (CPU seed set, default GPU set if GPU available)

set_submatrix(row_range, col_range, tensor)[source]

Set a submatrix of a rank-2 tensor for the given rows / cols.

set_subtensor_entry(corner_low, corner_high, tensor)[source]

Set a subtensor (potentially expensive as looping explicitly, inplace update).

Arguments

corner_lowlist of ints

The lower index of each dimension of the tensor to set. Length must match rank of tensor self.

corner_highlist of ints

The higher index of each dimension of the tensor to set. Length must match rank of tensor self.

tensorQteaTensor

Tensor to be set as subtensor. Rank must match tensor self. Dimensions must match corner_high - corner_low.

Examples

To set the tensor of shape 2x2x2 in a larger tensor self of shape 8x8x8 the corresponing call is in comparison to a numpy syntax:

  • self.set_subtensor_entry([2, 4, 2], [4, 6, 4], tensor)

  • self[2:4, 4:6, 2:4] = tensor

Or with variables and rank-3 tensors

  • self.set_subtensor_entry([a, b, c], [d, e, f], tensor)

  • self[a:d, b:e, c:f] = tensor

To be able to work with all ranks, we currently avoid the numpy syntax in our implementation.

property shape

Dimension of tensor along each dimension.

split_qr(legs_left, legs_right, perm_left=None, perm_right=None, is_q_link_outgoing=True, disable_streams=False)[source]

Split the tensor via a QR decomposition.

Parameters

selfinstance of QteaTensor

Tensor upon which apply the QR

legs_leftlist of int

Legs that will compose the rows of the matrix

legs_rightlist of int

Legs that will compose the columns of the matrix

perm_leftlist of int, optional

permutations of legs after the QR on left tensor

perm_rightlist of int, optional

permutation of legs after the QR on right tensor

disable_streamsboolean, optional

No effect here, but in general can disable streams to avoid nested generation of streams.

Returns

tens_left: instance of QteaTensor

unitary tensor after the QR, i.e., Q.

tens_right: instance of QteaTensor

upper triangular tensor after the QR, i.e., R

split_qrte(tens_right, singvals_self, operator=None, conv_params=None, is_q_link_outgoing=True)[source]

Perform an Truncated ExpandedQR decomposition, generalizing the idea of https://arxiv.org/pdf/2212.09782.pdf for a general bond expansion given the isometry center of the network on tens_left. It should be rather general for three-legs tensors, and thus applicable with any tensor network ansatz. Notice that, however, you do not have full control on the approximation, since you know only a subset of the singular values truncated.

Parameters

tens_left: xp.array

Left tensor

tens_right: xp.array

Right tensor

singvals_left: xp.array

Singular values array insisting on the link to the left of tens_left

operator: xp.array or None

Operator to contract with the tensors. If None, no operator is contracted

Returns

tens_left: ndarray

left tensor after the EQR

tens_right: ndarray

right tensor after the EQR

singvals: ndarray

singular values kept after the EQR

singvals_cutted: ndarray

subset of thesingular values cutted after the EQR, normalized with the biggest singval

split_rq(legs_left, legs_right, perm_left=None, perm_right=None, is_q_link_outgoing=True, disable_streams=False)[source]

Split the tensor via a RQ decomposition. The abstract class defines the RQ via a QR and permutation of legs, but we highly recommend overwriting this approach with an actual RQ.

Parameters

selfinstance of _AbstractQteaTensor

Tensor upon which apply the RQ

legs_leftlist of int

Legs that will compose the rows of the matrix (and the R matrix)

legs_rightlist of int

Legs that will compose the columns of the matrix (and the Q matrix)

perm_leftlist of int | None, optional

permutations of legs after the QR on left tensor Default to None (no permutation)

perm_rightlist of int | None, optional

permutation of legs after the QR on right tensor Default to None (no permutation)

is_q_link_outgoingint, optional

Direction of link, placeholder for symmetric tensors. Default to True.

disable_streamsboolean, optional

No effect here, but in general can disable streams to avoid nested generation of streams.

Returns

tens_left: instance of _AbstractQteaTensor

upper triangular tensor after the RQ, i.e., R

tens_right: instance of _AbstractQteaTensor

unitary tensor after the RQ, i.e., Q.

split_svd(legs_left, legs_right, perm_left=None, perm_right=None, contract_singvals='N', conv_params=None, no_truncation=False, is_link_outgoing_left=True, disable_streams=False)[source]

Perform a truncated Singular Value Decomposition by first reshaping the tensor into a legs_left x legs_right matrix, and permuting the legs of the ouput tensors if needed. If the contract_singvals = (‘L’, ‘R’) it takes care of renormalizing the output tensors such that the norm of the MPS remains 1 even after a truncation.

Parameters

selfinstance of QteaTensor

Tensor upon which apply the SVD

legs_leftlist of int

Legs that will compose the rows of the matrix

legs_rightlist of int

Legs that will compose the columns of the matrix

perm_leftlist of int, optional

permutations of legs after the SVD on left tensor

perm_rightlist of int, optional

permutation of legs after the SVD on right tensor

contract_singvals: string, optional
How to contract the singular values.

‘N’ : no contraction ‘L’ : to the left tensor ‘R’ : to the right tensor

conv_paramsTNConvergenceParameters, optional

Convergence parameters to use in the procedure. If None is given, then use the default convergence parameters of the TN. Default to None.

no_truncationboolean, optional

Allow to run without truncation Default to False (hence truncating by default)

disable_streamsboolean, optional

No effect here, but in general can disable streams to avoid nested generation of streams.

Returns

tens_left: instance of QteaTensor

left tensor after the SVD

tens_right: instance of QteaTensor

right tensor after the SVD

singvals: xp.ndarray

singular values kept after the SVD

singvals_cut: xp.ndarray

singular values cut after the SVD, normalized with the biggest singval

sqrtm()[source]

Calculate matrix-square-root for a rank-2 tensor.

Stack first and last link of tensor targeting MPS addition.

Stack two tensors along a given link.

Arguments

otherinstance of QteaTensor

Links must match self up to the specified link.

linkinteger

Stack along this link.

Returns

new_this : instance of :class:QteaTensor`

static static_is_gpu_available()[source]

Returns flag if GPU is available for this tensor class.

stream(disable_streams=False)[source]

Define a stream for any operation

Parameters

disable_streamsbool, optional

Allows to disable streams to avoid nested creation of streams. Globally, streams should be disabled via the set_streams_qteatensors function of the base tensor module. Default to False.

Returns

Context manager, e.g., to.cuda.Stream if on GPU nullcontext(AbstractContextManager) otherwise

Details

For multi-GPU applications, the device of the stream is selected as the device of the tensor at the time of the call. If one changes the device of the tensor self after creating the stream, the tensor’s device and the stream’s device will mismatch.

Extract and return a subtensor select range (lower, upper) for one link.

Extract and return a subtensor via indices for one link.

Arguments

linkint

Select only specific indices along this link (but all indices along any other link).

indslist[int]

Indices to be selected and stored in the subtensor.

Returns

subtensorQteaTensor

Subtensor with selected indices.

Details

The numpy equivalent is subtensor = tensor[:, :, inds, :] for a rank-4 tensor and link=2.

tensordot(other, contr_idx, disable_streams=False)[source]

Tensor contraction of two tensors along the given indices.

to_dense(true_copy=False)[source]

Return dense tensor (if true_copy=False, same object may be returned).

to_dense_singvals(s_vals, true_copy=False)[source]

Convert singular values to dense vector without symmetries.

trace(return_real_part=False, do_get=False)[source]

Take the trace of a rank-2 tensor.

transpose(permutation)[source]

Permute the links of the tensor and return new tensor.

transpose_update(permutation)[source]

Permute the links of the tensor inplace.

vector_with_dim_like(dim, dtype=None)[source]

Generate a vector in the native array of the base tensor.

write(filehandle, cmplx=None)[source]

Write tensor in original Fortran compatible way.

Details

  1. Number of links

  2. Line with link dimensions

  3. Entries of tensors line-by-line in column-major ordering.

zeros_like()[source]

Get a tensor same as self but filled with zeros.

class qtealeaves.tensors.DataMoverNumpyCupy[source]

Data mover to move QteaTensor between numpy and cupy.

Details

Streams are linked to device as indicated by the following page: https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#stream-and-event-behavior and multi-GPU behavior: https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#multi-gpu

async_move(tensor, device, stream=None)[source]

Move the tensor tensor to the device device asynchronously with respect to the main computational stream.

Parameters

tensor_AbstractTensor

The tensor to be moved

device: str

The device where to move the tensor

streamstream-object

Stream to be used to move the data if a stream different from the data mover’s stream should be used. Default to None (use DataMover’s stream)

property device_memory

Current memory occupied in the device.

sync_move(tensor, device)[source]

Move the tensor tensor to the device device synchronously with the main computational stream.

Parameters

tensor_AbstractTensor

The tensor to be moved

device: str

The device where to move the tensor

wait(device=None)[source]

Put a barrier for the streams and wait them.

Parameters

devicestr | None, optional

If None, all streams will be synchronized. Default to None

class qtealeaves.tensors._process_svd_ctrl(svd_ctrl, max_bond_dim, shape, device, contract_singvals)[source]

Process the svd_ctrl parameter for an SVD decomposition

Parameters

svd_ctrl: str

SVD identifier chosen by the user

max_bond_dimint

Maximum bond dimension

shape: Tuple[int]

Shape of the matrix to be split

device: str

Device where the splitting is taking place

contract_singvals: str

Where to contract the singvals

Return

str

The svd_ctrl after the double-check

Tensor Backend

class qtealeaves.tensors.TensorBackend(tensor_cls=<class 'qtealeaves.tensors.tensor.QteaTensor'>, base_tensor_cls=<class 'qtealeaves.tensors.tensor.QteaTensor'>, device='cpu', dtype=<class 'numpy.complex128'>, symmetry_injector=None, datamover=<qtealeaves.tensors.tensor.DataMoverNumpyCupy object>)[source]

Defines the complete tensor backend to be used. Contains the tensor class, the base tensor class in case it is needed for symmetric tensors, the target device, and the data type.

Parameters

tensor_cls: _AbstractTensor, optional

Tensor class. Might be dense or symmetric. Default to QteaTensor

base_tensor_cls: _AbstractTensor, optional

The dense tensor class if tensor_cls was symmetric. Same as tensor_cls for dense tensors. Default to QteaTensor.

device: str, optional

Device of the tensors. Devices available depend on tensor_cls. The possible device available are: - “cpu” - “gpu” - “cpu+gpu”, where the tensor network will be stored in the “cpu”,

but all the computational demanding tasks will be executed on the “gpu”.

Default to “cpu”.

dtype: np.dtype, optional

Type of the tensor network. Available types depends on ‘tensor_cls`. Default to np.complex128.

symmetry_injectorclass similar to AbelianSymmetryInjector or None

Provides inject_parse_symmetries, inject_trivial_symmetry, and inject_parse_sectors for parsing symmetries and sectors as well as providing the trivial symmetry representation. Default to None (only valid for no symmetries).

datamoverinstance of _AbstractDataMover

Data mover compatible with the base_tensor_cls Default to DataMoverNumpyCupy

property computational_device

Device where the computations are done

eye_like(link)[source]

Create identity, unlike version in _AbstractQteaTensor, no existing tensor is required.

Arguments

linksame as returned by links property, here integer.

Dimension of the square, identity matrix.

from_elem_array(array, **kwargs)[source]

Call the from_elem_array method of the underlying base_tensor_cls.

Parameters

arraytensor

Tensor to be converted into _AbstractQteaBaseTensor. Can be numpy or native native type of base tensor’s library.

Returns

tensor_AbstractBaseTensorClass

Tensor/array as Quantum Tea tensor.

property memory_device

Device where the tensor is stored

parse_sectors(params, sym)[source]

Parse the sectors via a function which has to be passed by the user to __init__.

parse_symmetries(params)[source]

Parse the symmetry via a function which has to be passed by the user to __init__.

set_seed(seed)[source]

Set the seed for numpy and the tensor backend if different from numpy. (tensor backend still depends on if it is available for now).

Arguments

seedlist[int]

List of integers used as a seed; list has length 4.

tensor_cls_kwargs()[source]

Returns the keywords arguments for an _AbstractQteaTensor.

trivial_symmetry()[source]

Get trivial symmetry via a function which has to be passed by the user to __init__.

Abstract tensor

class qtealeaves.tensors._AbstractQteaTensor(links, ctrl='Z', are_links_outgoing=None, base_tensor_cls=None, dtype=None, device=None)[source]

Tensor for Quantum Tea simulations.

Arguments

linkslist

Type of entries in list depends on tensor type and are either integers for dense tensors or some LinkType for symmetric tensors.

ctrlstr, optional

Initialization of tensor. Default to “Z”

are_links_outgoinglist of bools

Used in symmetric tensors only: direction of link in tensor. Length is same as rank of tensor.

base_tensor_clsvalid dense quantum tea tensor or None

Used in symmetric tensors only: class representing dense tensor

dtypedata type, optional

Valid data type for the underlying tensors.

devicedevice specification, optional

Valid device specification (depending on tensor).

abstractmethod add_update(other, factor_this=None, factor_other=None)[source]

Inplace addition as self = factor_this * self + factor_other * other.

abstractmethod are_equal(other, tol=1e-07)[source]

Check if two tensors are equal.

Define property of outgoing links as property (always False).

assert_identical_irrep(link_idx)[source]

Assert that specified link is identical irreps.

abstractmethod assert_identity(tol=1e-07)[source]

Check if tensor is an identity matrix.

assert_normalized(tol=1e-07)[source]

Raise exception if norm is not 1 up to tolerance.

assert_unitary(links, tol=1e-07)[source]

Raise exception if tensor is not unitary up to tolerance for given links.

Attach dummy link at given position (inplace update).

abstract property base_tensor_cls

Base tensor class.

abstractmethod conj()[source]

Return the complex conjugated in a new tensor.

abstractmethod conj_update()[source]

Apply the complex conjugate to the tensor in place.

abstractmethod convert(dtype=None, device=None, stream=None)[source]

Convert underlying array to the specified data type inplace.

abstractmethod static convert_operator_dict(op_dict, params=None, symmetries=None, generators=None, base_tensor_cls=None, dtype=None, device=None)[source]

Iterate through an operator dict and convert the entries.

Arguments

op_dictinstance of TNOperators

Contains the operators as xp.ndarray.

symmetries: list, optional, for compatability with symmetric tensors.

For symmetry, contains symmetries. Otherwise, must be empty list.

generatorslist, optional, for compatability with symmetric tensors.

For symmetries, contains generator of the symmetries as str for dict. Must be empty list.

base_tensor_clsNone, optional, for compatability with symmetric tensors.

For symmetries, must be valid base tensor class. Otherwise, no checks on this one here.

dtypedata type for xp, optional

Specify data type.

devicestr

Device for the simulation. Typically “cpu” and “gpu”, but depending on tensor backend.

abstractmethod convert_singvals(singvals, dtype=None, device=None, stream=None)[source]

Convert the singular values via a tensor.

abstractmethod copy(dtype=None, device=None)[source]

Make a copy of a tensor.

abstract property device

Device where the tensor is stored.

abstractmethod dot(other)[source]

Inner product of two tensors <self|other>.

abstract property dtype

Data type of the underlying arrays.

abstract property dtype_eps

Data type’s machine precision of the underlying arrays.

abstractmethod dtype_from_char(dtype)[source]

Resolve data type from chars C, D, S, Z and optionally H.

dtype_real()[source]

Get the data type at the same precision which represents real numbers.

Returns

dtypeclass for corresponding backend.

The data type will be determined via the mapping of the char data types C -> S, D -> D, S -> S, Z -> D, H -> H, I -> I.

dtype_to_char()[source]

Translate current data type of the tensor back to char C, D, S, Z, H, or I.

Returns

char : represent data type as a single letter.

Construct a dummy link. This method is particularly important for symmetries.

abstractmethod eig_api(matvec_func, links, conv_params, args_func=None, kwargs_func=None)[source]

Interface to hermitian eigenproblem

abstractmethod einsum(einsum_str, *others)[source]

Call to einsum with self as first tensor.

Arguments

einsum_strstr

Einsum contraction rule.

other: List[_AbstractQteaTensors]

2nd, 3rd, …, n-th tensor in einsum rule as positional arguments. Entries must be of same instance as self.

Results

tensor_AbstractQteaTensor

Contracted tensor according to the einsum rules.

Details

The call np.einsum(einsum_str, x.elem, y.elem, z.elem) translates into x.einsum(einsum_str, y, z) for x, y, and z being QteaTensor. Similar holds for other derivates and backend libraries.

Expand the link between a pair of tensors based on the ctrl parameter. “R” for random

abstractmethod eye_like(link)[source]

Generate identity matrix.

Arguments

selfinstance of QteaTensor

Extract data type etc from this one here.

linksame as returned by links property.

Dimension of the square, identity matrix.

Flip irreps on given links (symmetric tensors only).

static free_device_memory(device=None)[source]

Free the unused device memory that is otherwise occupied by the cache. This method SHOULD NOT free memory allocated for the computation.

Parameters

devicestr | None

If present, i.e., not None, only the corresponding device will be freed. The device is a string, e.g., “gpu:0”

Fuses one set of links to a single link (inplace-update).

abstractmethod get_entry()[source]

Get entry if scalar on host.

abstractmethod get_of(variable)[source]

Run the get method to transfer to host on variable (same device as self).

abstractmethod getsizeof()[source]

Size in memory (approximate, e.g., without considering small meta data).

abstractmethod is_close_identity(tol=1e-07)[source]

Check if rank-2 tensor is close to identity.

is_cpu(query=None)[source]

Check if device is CPU or not.

Parameters

querystr | None, optional

If given, check for this string. If None, self.device will be checked. Default to None.

Returns

is_cpubool

True if device is a CPU.

static is_cpu_static(device_str)[source]

Check if device is CPU or not.

Parameters

device_strstr

Check for this string if it corresponds to a CPU.

Returns

is_cpubool

True if device is a CPU.

abstractmethod is_dtype_complex()[source]

Check if data type is complex.

is_gpu(query=None)[source]

Check if device is GPU or not.

Parameters

querystr | None, optional

If given, check for this string. If None, self.device will be checked. Default to None.

Returns

is_gpubool

True if device is a GPU.

static is_gpu_static(device_str)[source]

Check if device is GPU or not.

Parameters

device_strstr

Check for this string if it is a GPU device.

Returns

is_gpubool

True if device is a GPU.

abstractmethod is_identical_irrep(link_idx)[source]

Check that the link at link_idx is identical irrep.

abstractmethod is_implemented_device(query)[source]

Check if argument query is an implemented device.

Check if the link at given index is at full bond dimension.

abstractmethod kron(other, idxs=None)[source]

Perform the kronecker product between two tensors. By default, do it over all the legs, but you can also specify which legs should be kroned over. The legs over which the kron is not done should have the same dimension.

abstract property linear_algebra_library

Specification of the linear algebra library used as string.

Specification of link with full information to reconstruct link.

classmethod mpi_bcast(tensor, comm, tn_mpi_types, tensor_backend, root=0)[source]

Broadcast tensor via MPI.

classmethod mpi_recv(from_, comm, tn_mpi_types, tensor_backend)[source]

Send tensor via MPI.

Arguments

from_integer

MPI process to receive tensor from.

comm : instance of MPI communicator to be used

tn_mpi_typesdict

Dictionary mapping dtype to MPI data types.

tensor_backend : instance of TensorBackend

abstractmethod mpi_send(to_, comm, tn_mpi_types)[source]

Send tensor via MPI.

Arguments

tointeger

MPI process to send tensor to.

comm : instance of MPI communicator to be used

tn_mpi_typesdict

Dictionary mapping dtype to MPI data types.

abstract property ndim

Rank of the tensor.

abstractmethod norm()[source]

Calculate the norm of the tensor <tensor|tensor>.

abstractmethod norm_sqrt()[source]

Calculate the square root of the norm of the tensor <tensor|tensor>.

abstractmethod normalize()[source]

Normalize tensor with sqrt(<tensor|tensor>).

abstractmethod random_unitary(links)[source]

Generate a random unitary tensor via performing a SVD on a random tensor, where a matrix dimension is specified with links. Tensor will be of the structure [link[0], .., link[-1], link[0], .., link[-1]].

abstractmethod randomize(noise=None)[source]

Randomizes the entries of self. noise : float | None The amount of noise added. None randomizes completely.

abstractmethod classmethod read(filehandle, dtype, device, base_tensor_cls, cmplx=True, order='F')[source]

Read a tensor from file.

Remove the dummy link at given position (inplace update).

abstractmethod restrict_irreps(link_idx, sector)[source]

Restrict, i.e., project, link to a sector (needed for symmetric tensors).

sanity_check()[source]

Quick set of checks for tensor.

Scale tensor along one link at link_idx with weights. Can do inverse, too.

Scale tensor along one link at link_idx with weights (inplace update).

abstractmethod set_diagonal_entry(position, value)[source]

Set the diagonal element in a rank-2 tensor (inplace update)

abstractmethod set_matrix_entry(idx_row, idx_col, value)[source]

Set element in a rank-2 tensor (inplace update)

Calculate the property of a missing link in a list.

abstract property shape

Dimension of tensor along each dimension.

Split a link into two, where one carries the degeneracy, the other the charge.

Arguments

link_idxint

Link to be split.

Returns

_AbstractQteaTensor

New tensor with link at position link_idx split into two links at link_idx (degeneracy) and link_idx + 1 (charge). Links originally after link_idx follow shifted by one index.

abstractmethod split_qr(legs_left, legs_right, perm_left=None, perm_right=None, is_q_link_outgoing=True, disable_streams=False)[source]

Split the tensor via a QR decomposition.

abstractmethod split_qrte(tens_right, singvals_self, operator=None, conv_params=None, is_q_link_outgoing=True)[source]

Split via a truncated expanded QR.

split_rq(legs_left, legs_right, perm_left=None, perm_right=None, is_q_link_outgoing=True, disable_streams=False)[source]

Split the tensor via a RQ decomposition. The abstract class defines the RQ via a QR and permutation of legs, but we highly recommend overwriting this approach with an actual RQ.

Parameters

selfinstance of _AbstractQteaTensor

Tensor upon which apply the RQ

legs_leftlist of int

Legs that will compose the rows of the matrix (and the R matrix)

legs_rightlist of int

Legs that will compose the columns of the matrix (and the Q matrix)

perm_leftlist of int | None, optional

permutations of legs after the QR on left tensor Default to None (no permutation)

perm_rightlist of int | None, optional

permutation of legs after the QR on right tensor Default to None (no permutation)

is_q_link_outgoingint, optional

Direction of link, placeholder for symmetric tensors. Default to True.

disable_streamsboolean, optional

Can disable streams to avoid nested generation of streams.

Returns

tens_left: instance of _AbstractQteaTensor

upper triangular tensor after the RQ, i.e., R

tens_right: instance of _AbstractQteaTensor

unitary tensor after the RQ, i.e., Q.

abstractmethod split_svd(legs_left, legs_right, perm_left=None, perm_right=None, contract_singvals='N', conv_params=None, no_truncation=False, is_link_outgoing_left=True, disable_streams=False)[source]

Split tensor via SVD for a bipartion of links.

Stack first and last link of tensor targeting MPS addition.

Parameters

other_AbstractQteaTensor (same type as self)

Second tensor to be stacked onto self for first and last link.

Returns

stacked_tensor_AbstractQteaTensor (same type as self)

New tensor with dimension d1 = s1 + o1, d2 = s2 = o2, d3 = s3 + o3. The dimensions of self are (s1, s2, s3) and the dimensions of other are (o1, o2, o3).

Stack two tensors along a given link.

abstractmethod stream(disable_streams=False)[source]

Define a stream for any operation

Parameters

disable_streamsbool, optional

Allows to disable streams to avoid nested creation of streams. Globally, streams should be disabled via the set_streams_* function of the corresponding base tensor module. Default to False.

Returns

Context manager, e.g., Stream if stream exists for tensor backend nullcontext(AbstractContextManager) otherwise

abstractmethod tensordot(other, contr_idx, disable_streams=False)[source]

Tensor contraction of two tensors along the given indices.

abstractmethod to_dense(true_copy=False)[source]

Return dense tensor (if true_copy=False, same object may be returned).

abstractmethod to_dense_singvals(s_vals, true_copy=False)[source]

Convert singular values to dense vector without symmetries.

abstractmethod trace(return_real_part=False, do_get=False)[source]

Take the trace of a rank-2 tensor.

abstractmethod trace_one_dim_pair(links)[source]

Trace a pair of links with dimenion one. Inplace update.

abstractmethod transpose(permutation)[source]

Permute the links of the tensor and return new tensor.

abstractmethod transpose_update(permutation)[source]

Permute the links of the tensor inplace.

abstractmethod write(filehandle, cmplx=None)[source]

Write tensor.

abstractmethod zeros_like()[source]

Get a tensor with the same links as self but filled with zeros.

class qtealeaves.tensors._AbstractQteaBaseTensor(*args, **kwargs)[source]
abstractmethod assert_diagonal(tol=1e-07)[source]

Check that tensor is a diagonal matrix up to tolerance.

abstractmethod assert_int_values(tol=1e-07)[source]

Check that there are only integer values in the tensor.

abstractmethod assert_real_valued(tol=1e-07)[source]

Check that all tensor entries are real-valued.

property base_tensor_cls

Base tensor class.

concatenate_vectors(vectors, dtype, dim=None)[source]

Concatenate vectors of the underlying numpy / cupy / torch / etc tensors.

Arguments*

vectorslist

List of one-dimensional arrays.

dtypedata type

Data type of concatenated vectors.

dimint | None

Total dimension of concatenated vectors. If None, calculated on the fly. Default to None

Returns

vecone-dimensional array of corresponding backend library, e.g., numpy ndarray

The elements in the list are concatenated in order, e.g., input [[1, 2], [6, 5, 3]] will result in [1, 2, 6, 5, 3].

mappingdict

Keys are the index of the individual vectors in the list vectors. Values are tuples with two integers with the lower and higher bound, e.g., {0 : (0, 2), 1: (2, 5)} for the example in vec in the previous return variable.

Details

Used to concatenate singular values for symmetric tensors in SVD, which is needed as jax and tensorflow do not support x[:] assignments.

abstractmethod diag(real_part_only=False, do_get=False)[source]

Return either the diagonal of an input rank-2 tensor or a rank-2 tensor of an input diagonal.

abstractmethod eig()[source]

Compute eigenvalues and eigenvectors of a two-leg tensor

static einsum_optimization_level(tensors, einsum_str)[source]

Heuristic to get an optimization level for einsum contractions. The integer has to be translated into the backend specific strings.

Parameters

tensorslist[_AbstractQteaTensors]

Tensors involved in the einsum contraction.

einsum_strstr

Summation rule for einsum.

Returns

optimization_levelint

Integer being 0, 1, or 2 with 0 the lowest need for optimization. The cost is calculated via the product of each unique link. Starting from three tensors, cost of 1e8 has level 1, cost of 1e12 has level 2.

property elem

The array representing the tensor entries.

abstractmethod elementwise_abs_smaller_than(value)[source]

Return boolean if each tensor element is smaller than value

Expand the link between a pair of tensors. If ctrl=”R”, the expansion is random

Arguments

other : instance of :class`QteaTensor`

link_selfint

Expand this link in self

link_otherint

Expand this link in other. Link must be a match (dimension etc.)

ctrlstr, optional

How to fill the extension. Default to “R” (random)

Returns

new_thisinstance of :class`QteaTensor`

Expanded version of self

new_otherinstance of :class`QteaTensor`

Expanded version of other

abstractmethod expand_tensor(link, new_dim, ctrl='R')[source]

Expand tensor along given link and to new dimension.

abstractmethod expm(fuse_point=None, prefactor=1)[source]

Take the matrix exponential with a scalar prefactor, i.e., Exp(prefactor * self).

abstractmethod flatten()[source]

Returns flattened version (rank-1) of dense array in native array type.

abstractmethod classmethod from_elem_array(tensor, dtype=None, device=None)[source]

New tensor from array.

abstractmethod static get_default_datamover()[source]

The default datamover compatible with this class.

abstractmethod get_diag_entries_as_int()[source]

Return diagonal entries of rank-2 tensor as integer on host.

abstractmethod get_submatrix(row_range, col_range)[source]

Extract a submatrix of a rank-2 tensor for the given rows / cols.

is_identical_irrep(link_idx)[source]

Check that the link at link_idx is identical irrep.

abstractmethod mask_to_device(mask)[source]

Send a mask to the device where the tensor is.

abstractmethod mask_to_host(mask)[source]

Send a mask to the host.

pad(link, new_dim, ctrl='R')[source]

Pad a tensor along given link and to new dimension. It is a wapper around self.expand_tensor. The padding is added at the end.

Parameters

linkint

Link to expand

new_dimint

New dimension of the tensor

ctrlstr | scalar

Value for the padding

Returns

_AbstractQteaTensor

The padded tensor

abstractmethod permute_rows_cols_update(inds)[source]

Permute rows and columns of rank-2 tensor with inds. Inplace update.

abstractmethod prepare_eig_api(conv_params)[source]

Return variables for eigsh.

randomize(noise=None)[source]

Randomizes the entries of self.

Parameters

noisefloat | None

The amount of noise added. None randomizes completely.

abstractmethod reshape(shape, **kwargs)[source]

Reshape a tensor.

abstractmethod reshape_update(shape, **kwargs)[source]

Reshape tensor dimensions inplace.

restrict_irreps(link_idx, sector)[source]

Restrict, i.e., project, link to a sector (needed for symmetric tensors).

abstractmethod set_submatrix(row_range, col_range, tensor)[source]

Set a submatrix of a rank-2 tensor for the given rows / cols.

abstractmethod set_subtensor_entry(corner_low, corner_high, tensor)[source]

Set a subtensor (potentially expensive as looping explicitly, inplace update).

Arguments

corner_lowlist of ints

The lower index of each dimension of the tensor to set. Length must match rank of tensor self.

corner_highlist of ints

The higher index of each dimension of the tensor to set. Length must match rank of tensor self.

tensorQteaTensor

Tensor to be set as subtensor. Rank must match tensor self. Dimensions must match corner_high - corner_low.

Examples

To set the tensor of shape 2x2x2 in a larger tensor self of shape 8x8x8 the corresponing call is in comparison to a numpy syntax:

  • self.set_subtensor_entry([2, 4, 2], [4, 6, 4], tensor)

  • self[2:4, 4:6, 2:4] = tensor

Or with variables and rank-3 tensors

  • self.set_subtensor_entry([a, b, c], [d, e, f], tensor)

  • self[a:d, b:e, c:f] = tensor

To be able to work with all ranks, we currently avoid the numpy syntax in our implementation.

Split a link into two, where one carries the degeneracy, the other the charge.

Extract and return a subtensor select range (lower, upper) for one line.

Extract and return a subtensor via indices for one link.

Arguments

linkint

Select only specific indices along this link (but all indices along any other link).

indslist[int]

Indices to be selected and stored in the subtensor.

Returns

subtensor_AbstractQteaTensor

Subtensor with selected indices.

Details

The numpy equivalent is subtensor = tensor[:, :, inds, :] for a rank-4 tensor and link=2.

trace_one_dim_pair(links)[source]

Trace a pair of links with dimenion one. Inplace update.

abstractmethod vector_with_dim_like(dim, dtype=None)[source]

Generate a vector in the native array of the base tensor.

class qtealeaves.tensors._AbstractDataMover[source]

Abstract class for moving data between different devices

Class attributes

tensor_clsTuple[_AbstractTensor]

Tensor classes handled by the datamover

abstractmethod async_move(tensor, device, stream=None)[source]

Move the tensor tensor to the device device asynchronously with respect to the main computational stream

Parameters

tensor_AbstractTensor

The tensor to be moved

device: str

The device where to move the tensor

check_tensor_cls_compatibility(tensor_cls)[source]

Check if a tensor_cls can be handled by the datamover

Parameters

tensor_cls_AbstractTensor

The tensor class to check

move(tensor, device, sync=True)[source]

Move the tensor tensor to the device device

Parameters

tensor_AbstractTensor

The tensor to be moved

device: str

The device where to move the tensor

syncbool | stream, optional

If True, move synchronously with the default cuda stream. If False, move asynchronously with additional stream in data mover. Otherwise, assume argument is the stream to be used. Stream argument might differ for backends.

abstractmethod sync_move(tensor, device)[source]

Move the tensor tensor to the device device synchronously with the main computational stream

Parameters

tensor_AbstractTensor

The tensor to be moved

device: str

The device where to move the tensor

abstractmethod wait()[source]

Put a barrier for the streams and wait them